{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# about Class（类）\n",
    "## 1 定义与使用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Overwriting aboutClass/define_and_use.py\n"
     ]
    }
   ],
   "source": [
    "%%writefile aboutClass/define_and_use.py\n",
    "from random import randint\n",
    "class Boxer:\n",
    "    def __init__(self,name):\n",
    "        self.name = name\n",
    "        self.life = 100\n",
    "        self.pet = None\n",
    "    def intro(self):\n",
    "        if self.pet == None:\n",
    "            print('my name is {},and I hate dog '.format(self.name))\n",
    "        else:\n",
    "            print('my name is {},and I have a dog {}'.format(self.name,self.pet.name))\n",
    "    def punch(self):\n",
    "        side = randint(0,1)\n",
    "        print('{} puch in {} '.format(self.name,side),end='--->')\n",
    "        return side\n",
    "    def dodge(self):\n",
    "        side = randint(0,1)\n",
    "        print('{} dodge in {}'.format(self.name,side) )\n",
    "        return side\n",
    "    def adopt(self,dog):\n",
    "        self.pet = dog\n",
    "        dog.adopted(self)\n",
    "    def show(self):\n",
    "        print('{}={}'.format(self.name,self.life))\n",
    "    \n",
    "class Dog:\n",
    "    def __init__(self,pname,prace):\n",
    "        self.name = pname\n",
    "        self.race = prace\n",
    "        self.owner = None\n",
    "    def bite(self,person):\n",
    "        print('{} is biting {}'.format(self.name,person.name))\n",
    "        person.life = person.life - 5\n",
    "    def adopted(self,powner):\n",
    "        self.owner = powner\n",
    "    def intro(self):\n",
    "        if self.owner == None:\n",
    "            print('wangwang, my name is {}, I want a hoster'.format(self.name))\n",
    "        else:\n",
    "            print('wangwang, my name is {}, my owner is {}'.format(self.name,self.owner.name))\n",
    "    \n",
    "\n",
    "\n",
    "\n",
    "b1 = Boxer('Ali')\n",
    "b2 = Boxer('tenson')\n",
    "b1.intro()\n",
    "\n",
    "d1 = Dog('xiaohua','hashiqi')\n",
    "d1.intro()\n",
    "\n",
    "b1.adopt(d1)\n",
    "\n",
    "b1.pet.bite(b1)\n",
    "b1.show()\n",
    "'''\n",
    "round = 0\n",
    "while round < 2:\n",
    "    print('\\n{:*^30d}'.format(round+1))\n",
    "    if b1.punch() != b2.dodge():\n",
    "        b2.life = b2.life -10\n",
    "    if b2.punch() != b1.dodge():\n",
    "        b1.life = b1.life -10\n",
    "    round = round + 1\n",
    "    b1.show()\n",
    "    b2.show()\n",
    "'''"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "注意在上面的程序中，有几个对象：\n",
    "1个class（或type）对象。\n",
    "2个instance（实例）对象。\n",
    "\n",
    "\n",
    "区别class对象和实例对象，可以显示对象的id来进行区分。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "boxer id is 140660431966216\n",
      "b1 id is 140660434836000\n",
      "b2 id is 140660434931952\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "4331684552"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "print('boxer id is {}'.format(id(Boxer)))\n",
    "print('b1 id is {}'.format(id(b1)))\n",
    "print('b2 id is {}'.format(id(b2)))\n",
    "dir(boxer)\n",
    "id(None)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2 对象广义的属性\n",
    "方法也是对象的属性。\n",
    "\n",
    "\n",
    "attribute table\n",
    "\n",
    "\n",
    "name | value | type\n",
    ":-:|:-:|:-:\n",
    "name | 'Ali' | str\n",
    "life | 100 |int\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing aboutClass/understand_world.py\n"
     ]
    }
   ],
   "source": [
    "%%writefile aboutClass/understand_world.py\n",
    "from random import randint\n",
    "class Boxer:\n",
    "    def __init__(self,name):\n",
    "        self.name = name\n",
    "        self.life = 100\n",
    "        self.pet = None\n",
    "    def intro(self):\n",
    "        if self.pet == None:\n",
    "            print('my name is {},and I hate dog '.format(self.name))\n",
    "        else:\n",
    "            print('my name is {},and I have a dog {}'.format(self.name,self.pet.name))\n",
    "    def punch(self):\n",
    "        side = randint(0,1)\n",
    "        print('{} puch in {} '.format(self.name,side),end='--->')\n",
    "        return side\n",
    "    def dodge(self):\n",
    "        side = randint(0,1)\n",
    "        print('{} dodge in {}'.format(self.name,side) )\n",
    "        return side\n",
    "    def adopt(self,dog):\n",
    "        self.pet = dog\n",
    "        dog.adopted(self)\n",
    "    def show(self):\n",
    "        print('{}={}'.format(self.name,self.life))\n",
    "    \n",
    "class Dog:\n",
    "    def __init__(self,pname,prace):\n",
    "        self.name = pname\n",
    "        self.race = prace\n",
    "        self.owner = None\n",
    "    def bite(self,person):\n",
    "        print('{} is biting {}'.format(self.name,person.name))\n",
    "        person.life = person.life - 5\n",
    "    def adopted(self,powner):\n",
    "        self.owner = powner\n",
    "    def intro(self):\n",
    "        if self.owner == None:\n",
    "            print('wangwang, my name is {}, I want a hoster'.format(self.name))\n",
    "        else:\n",
    "            print('wangwang, my name is {}, my owner is {}'.format(self.name,self.owner.name))\n",
    "    \n",
    "\n",
    "\n",
    "\n",
    "b1 = Boxer('Ali')\n",
    "b2 = Boxer('tenson')\n",
    "b1.intro()\n",
    "\n",
    "d1 = Dog('xiaohua','hashiqi')\n",
    "d1.intro()\n",
    "\n",
    "b1.adopt(d1)\n",
    "\n",
    "b1.pet.bite(b1)\n",
    "b1.show()\n",
    "\n",
    "for i in [b1,b2]:\n",
    "    print(\"\\n{:*^30s}\".format(i.name))\n",
    "    print('name: id ={} value = {}'.format(id(i.name),i.name))\n",
    "    print('life: id ={} value = {}'.format(id(i.life),i.life))\n",
    "    print('pet: id ={} value = {}'.format(id(i.pet),i.pet))\n",
    "    print('punch: id ={} value = {}'.format(id(i.punch),i.punch))\n",
    "    print('intro: id ={} value = {}'.format(id(i.intro),i.intro))\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing instenceattributes.py\n"
     ]
    }
   ],
   "source": [
    "%%writefile instenceattributes.py\n",
    "class Simple:\n",
    "    def __init__(self,pa1):\n",
    "        self._a1 = pa1\n",
    "        pass\n",
    "a = Simple(100)\n",
    "a.a2 = '123'\n",
    "def fun1():\n",
    "    print('i am fun1')\n",
    "print(a._a1)\n",
    "a.m1 = fun1\n",
    "a.m1()\n",
    "a.a3 = 12\n",
    "print(a.__dict__)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2 语法蜜糖背后的故事\n",
    "上面在生成和使用实例对象时，我们实际采用了语法蜜糖。理解语法蜜糖后面的故事，可以使我们的概念更清楚。\n",
    "\n",
    "\n",
    "我们说过，对象的功能通过方法来实现。既然class对象的一个重要功能就是生成实例对象，那么他就该有一个方法。是的，这个方法就是```__new__```。\n",
    "\n",
    "![setattr](aboutClass/setAttr.png)\n",
    "![setattr](aboutClass/setAttrExplain.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'boxer' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-1-efe88d6475ff>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mdir\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mboxer\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mNameError\u001b[0m: name 'boxer' is not defined"
     ]
    }
   ],
   "source": [
    "dir(boxer)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "my name is Holifield,and I hate dog \n"
     ]
    }
   ],
   "source": [
    "\n",
    "b1 = Boxer.__new__(Boxer)\n",
    "b1.__init__('Holifield')\n",
    "b2 = Boxer('Telson')\n",
    "b1.intro()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3 类也是对象\n",
    "\n",
    "\n",
    "- 类方法 属于类对象的方法\n",
    "- 类属性 属于类对象的属性\n",
    "\n",
    "访问规则：\n",
    "- 用类对象的名字进行访问\n",
    "- 实例对象也可以访问，但注意唯一性。\n",
    "- 冲突：如果实例对象也有该属性，则访问到自己的实例属性，而不是类属性。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Overwriting aboutClass/class_method.py\n"
     ]
    }
   ],
   "source": [
    "%%writefile aboutClass/class_method.py\n",
    "from random import randint\n",
    "class Boxer:\n",
    "    total = 0       #类属性\n",
    "    @classmethod    #类方法 classMethod\n",
    "    def counter(cls):\n",
    "        print('there are {} boxer in this world.'.format(cls.total))\n",
    "        \n",
    "\n",
    "    def __init__(self,name):\n",
    "        Boxer.total = Boxer.total + 1  #注意，实例方法怎样访问类属性\n",
    "        #Boxer.total = self.total + 1  #功能同上句，为什么？实例对象名可以访问类属性。 \n",
    "        #self.total = self.total + 1   # 会报错，为什么？等号是命名\n",
    "        self.name = name\n",
    "        self.life = 100\n",
    "        self.pet = None\n",
    "    def intro(self):\n",
    "        if self.pet == None:\n",
    "            print('my name is {},and I hate dog '.format(self.name))\n",
    "        else:\n",
    "            print('my name is {},and I have a dog {}'.format(self.name,self.pet.name))\n",
    "    def punch(self):\n",
    "        side = randint(0,1)\n",
    "        print('{} puch in {} '.format(self.name,side),end='--->')\n",
    "        return side\n",
    "    def dodge(self):\n",
    "        side = randint(0,1)\n",
    "        print('{} dodge in {}'.format(self.name,side) )\n",
    "        return side\n",
    "    def adopt(self,dog):\n",
    "        self.pet = dog\n",
    "        dog.adopted(self)\n",
    "    def show(self):\n",
    "        print('{}={}'.format(self.name,self.life))\n",
    "    \n",
    "class Dog:\n",
    "    def __init__(self,pname,prace):\n",
    "        self.name = pname\n",
    "        self.race = prace\n",
    "        self.owner = None\n",
    "    def bite(self,person):\n",
    "        print('{} is biting {}'.format(self.name,person.name))\n",
    "        person.life = person.life - 5\n",
    "    def adopted(self,powner):\n",
    "        self.owner = powner\n",
    "    def intro(self):\n",
    "        if self.owner == None:\n",
    "            print('wangwang, my name is {}, I want a hoster'.format(self.name))\n",
    "        else:\n",
    "            print('wangwang, my name is {}, my owner is {}'.format(self.name,self.owner.name))\n",
    "    \n",
    "\n",
    "\n",
    "\n",
    "b1 = Boxer('Ali')\n",
    "b2 = Boxer('tenson')\n",
    "Boxer.counter()\n",
    "#print('b1 acccess total = {}'.format(b1.total))\n",
    "\n",
    "b1.total = 10\n",
    "Boxer.counter()\n",
    "print(b1.total)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4 类的静态方法，一切方法的根源"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n",
      "<__main__.Boxer object at 0x7ffd59c42400>\n",
      "<class '__main__.Boxer'>\n",
      "my name is Ali,and I hate dog \n",
      "my name is Ali,and I hate dog \n",
      "there are 1 boxer in this world.\n",
      "\n",
      "************Boxer*************\n",
      "counter: id =140726108307976 value = <bound method Boxer.counter of <class '__main__.Boxer'>>\n",
      "add: id =140726109468328 value = <function Boxer.add at 0x7ffd59c3f6a8>\n",
      "intro: id =140726109467512 value = <function Boxer.intro at 0x7ffd59c3f378>\n",
      "intro: id =140726108307976 value = <bound method Boxer.intro of <__main__.Boxer object at 0x7ffd59c42400>>\n"
     ]
    }
   ],
   "source": [
    "#%%writefile aboutClass/static_method.py\n",
    "from random import randint\n",
    "class Boxer:\n",
    "    total = 0       #类属性\n",
    "    @classmethod    #类方法 classMethod\n",
    "    def counter(cls):\n",
    "        print('there are {} boxer in this world.'.format(cls.total))\n",
    "    @staticmethod\n",
    "    def add(a,b):    #静态方法\n",
    "        return a+b\n",
    "    @staticmethod\n",
    "    def add2(obj,a,b):\n",
    "        print(obj)\n",
    "        return a+b\n",
    "    def __init__(self,name):\n",
    "        Boxer.total = Boxer.total + 1  #注意，实例方法怎样访问类属性\n",
    "        self.name = name\n",
    "        self.life = 100\n",
    "        self.pet = None\n",
    "    def intro(self):\n",
    "        if self.pet == None:\n",
    "            print('my name is {},and I hate dog '.format(self.name))\n",
    "        else:\n",
    "            print('my name is {},and I have a dog {}'.format(self.name,self.pet.name))\n",
    "    def punch(self):\n",
    "        side = randint(0,1)\n",
    "        print('{} puch in {} '.format(self.name,side),end='--->')\n",
    "        return side\n",
    "    def dodge(self):\n",
    "        side = randint(0,1)\n",
    "        print('{} dodge in {}'.format(self.name,side) )\n",
    "        return side\n",
    "    def adopt(self,dog):\n",
    "        self.pet = dog\n",
    "        dog.adopted(self)\n",
    "    def show(self):\n",
    "        print('{}={}'.format(self.name,self.life))\n",
    "    \n",
    "class Dog:\n",
    "    def __init__(self,pname,prace):\n",
    "        self.name = pname\n",
    "        self.race = prace\n",
    "        self.owner = None\n",
    "    def bite(self,person):\n",
    "        print('{} is biting {}'.format(self.name,person.name))\n",
    "        person.life = person.life - 5\n",
    "    def adopted(self,powner):\n",
    "        self.owner = powner\n",
    "    def intro(self):\n",
    "        if self.owner == None:\n",
    "            print('wangwang, my name is {}, I want a hoster'.format(self.name))\n",
    "        else:\n",
    "            print('wangwang, my name is {}, my owner is {}'.format(self.name,self.owner.name))\n",
    "    \n",
    "\n",
    "\n",
    "\n",
    "b1 = Boxer('Ali')\n",
    "print(b1.add(1,2))\n",
    "Boxer.add2(b1,1,2)\n",
    "Boxer.add2(Boxer,1,2)\n",
    "\n",
    "b1.intro()    #与下面一句功能完全相同\n",
    "Boxer.intro(b1)\n",
    "\n",
    "print(\"\\n{:*^30s}\".format('Boxer'))\n",
    "print('counter: id ={} value = {}'.format(id(Boxer.counter),Boxer.counter))  #classmethod\n",
    "print('add: id ={} value = {}'.format(id(Boxer.add),Boxer.add))              #staticmethod     \n",
    "print('intro: id ={} value = {}'.format(id(Boxer.intro),Boxer.intro))        #instancemethod\n",
    "print('intro: id ={} value = {}'.format(id(b1.intro),b1.intro))        #instancemethod\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看出：\n",
    "- 对与类中定义的所有方法，python会将其看作静态方法。\n",
    "- 对于实例方法，在生成实例时，python会为该实例生成一个实例方法。\n",
    "- 对于类方法，在类的定义中，python为该类生成一个类方法\n",
    "- 所谓生成，就是绑定（bound）。其实python为每个实例提供了一个专门用于绑定的函数对象，该对象负责所有的实例方法的绑定，所以你看到同一个实例对象的所有实例方法的id都相同。而不同的实例对象（当然属于同一个类），它们的绑定函数就不一样。所以也可以把方法理解为对象的属性，同类对象具有相同的属性名称，但拥有不同的属性值（不同的对象）。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5 继承"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Overwriting aboutClass/Person.py\n"
     ]
    }
   ],
   "source": [
    "%%writefile aboutClass/Person.py\n",
    "class Person(object):\n",
    "    personNum = 0\n",
    "    @classmethod\n",
    "    def howmanyPerson(cls):\n",
    "        print('there are {} people in the world'.format(cls.personNum))    \n",
    "    def __init__(self,pnick,psex,page):\n",
    "        Person.personNum = self.personNum + 1\n",
    "        self.nick = pnick\n",
    "        self.sex = psex\n",
    "        self.age = page\n",
    "    def intro(self):\n",
    "        sexTuple =('male','female')\n",
    "        print('I am  {} and  {} and  {} years old'.format(self.nick,sexTuple[self.sex],self.age))\n",
    "    def __add__(self,pother):\n",
    "        from random import randint\n",
    "        tsex = randint(0,1)\n",
    "        baby = Person('Noname',tsex,1)\n",
    "        return baby\n",
    "p1 = Person('jhon',0,18)\n",
    "p1.intro()\n",
    "p2 = Person('rose',1,18)\n",
    "p2.intro()\n",
    "baby = p1 + p2\n",
    "baby.intro()\n",
    "\n",
    "Person.howmanyPerson()  #与下一句相同\n",
    "#p1.howmanyPerson()\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Overwriting aboutClass/Man.py\n"
     ]
    }
   ],
   "source": [
    "%%writefile aboutClass/Man.py\n",
    "class Man(Person):\n",
    "    manNum = 0\n",
    "    @classmethod\n",
    "    def howmanyMan(cls):\n",
    "        print('there are {} men in this world'.format(cls.manNum))\n",
    "    def __init__(self,pnick,page):\n",
    "        Person.__init__(self,pnick,0,page)\n",
    "        self.wife = None\n",
    "    def marry(self,pwife):\n",
    "        self.wife = pwife\n",
    "    def intro(self):\n",
    "        super().intro()\n",
    "        #Person.intro(self)\n",
    "        if self.wife == None:\n",
    "            print('I am sigle!!!')\n",
    "        else:\n",
    "            print('I am married ')\n",
    "class Woman(Person):\n",
    "    WomanNum = 0\n",
    "    @classmethod\n",
    "    def howmanyWoman(cls):\n",
    "        print('there are {} women in this world'.format(cls.WomanNum))\n",
    "    def __init__(self,pnick,page):\n",
    "        Person.__init__(self,pnick,1,page)\n",
    "        self.child = None\n",
    "    def born(self):\n",
    "        from random import randint\n",
    "        tsex =randint(0,1)\n",
    "        if tsex == 0:\n",
    "            baby = Man('noName',1)\n",
    "        else:\n",
    "            baby = Man('noName',1)\n",
    "        self.child = baby\n",
    "        return baby\n",
    "    def intro(self):\n",
    "        super().intro()\n",
    "        if self.child == None:\n",
    "            print('I have no child!!!')\n",
    "        else:\n",
    "            print('I have a child ')\n",
    "        \n",
    "\n",
    "m1 = Man(\"john\",28)\n",
    "m1.intro()\n",
    "w1 = Woman('rose',18)\n",
    "w1.intro()\n",
    "m1.marry(w1)\n",
    "m1.intro()\n",
    "b1 = w1.born()\n",
    "m1.intro()\n",
    "b1.intro()\n",
    "\n",
    "print(isinstance(m1,object))\n",
    "print(isinstance(m1,Woman))\n",
    "print(isinstance(m1,Person))\n",
    "print(issubclass(Man,Person))\n",
    "print(issubclass(Woman,Person))\n",
    "print(issubclass(Man,object))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6 隐藏属性和方法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing advancedClass/privateAM.py\n"
     ]
    }
   ],
   "source": [
    "%%writefile aboutClass/privateAM.py\n",
    "class Student(object):\n",
    "    def __init__(self):\n",
    "        self.__male = True\n",
    "    def __speak(sef):\n",
    "        print('hello')\n",
    "class GirlStudent(Student):\n",
    "    def __init__(self):\n",
    "        Student.__init__(self)\n",
    "    def intro(self):\n",
    "        Student._Student__speak(self)\n",
    "        print('I am girl')\n",
    "        \n",
    "s1 = Student()\n",
    "#print(s1.__male)\n",
    "print(hasattr(s1,'__male'))\n",
    "print(hasattr(s1,'_Student__male'))\n",
    "print(s1._Student__male)\n",
    "\n",
    "s1._Student__speak()\n",
    "\n",
    "\n",
    "g1 = GirlStudent()\n",
    "g1.intro()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 7 其它函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Writing aboutClass/otherfuncs.py\n"
     ]
    }
   ],
   "source": [
    "%%writefile aboutClass/otherfuncs.py\n",
    "print(hasattr(m1,'name'))\n",
    "setattr(m1,'test',10)\n",
    "print(m1.test)\n",
    "print(getattr(m1,'test'))\n",
    "setattr(Man,'weight',100)\n",
    "print(Man.weight)\n",
    "dir(m1)\n",
    "delattr(Man,'weight')\n",
    "dir(Man)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
